package controllers

import (
    "gouniapp/configs"
	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
	"golang.org/x/sync/singleflight"
	"gorm.io/datatypes"
	"encoding/json"
	"gorm.io/gorm"
    "crypto/rand"
    "encoding/hex"
	"log"
	"strings"
	"errors"
	"time"
	"net/http"
	"fmt"
)

// 小程序获取配置
func Qdgetconfig(c *gin.Context) {
    type Myconfig struct {
    	Server struct {
    		URL         string   `json:"url"`
    		Name        string   `json:"name"`
    		Reg         string   `json:"reg"` //开启注册
    		Jfsc        string   `json:"jfsc"`//开启积分商城
    	} `json:"server"`
    }
	myconfig := Myconfig{}
	if err := configs.Config.Unmarshal(&myconfig); err != nil {
		JsonResponse(c, http.StatusInternalServerError, "配置解析失败", err.Error())
		return
	}
	JsonResponse(c, http.StatusOK, "获取成功", myconfig)
}

// 移动端首页
func Home(c *gin.Context) {
	c.HTML(200, "index.html", gin.H{})
}

// pc端首页
func PcHome(c *gin.Context) {
    name := configs.Config.GetString("server.name")
    shuiyin := configs.Config.GetString("server.shuiyin")
    baseurl := configs.Config.GetString("server.url")
    footer := configs.Config.GetString("server.footer")
    c.HTML(200, "pc.html", gin.H{
        "baseurl":    baseurl,
        "title":      name,
        "shuiyin":    shuiyin,
        "version":    time.Now().Unix(),        // 防止缓存
        "staticBase": "/pc_static",             // PC静态资源路径
        "componentBase": "/pc_component",       // 组件基础路径
        "configs": map[string]interface{}{      // 初始配置数据
            "footer": footer,
            "name":   name,
        },
    })
}

var wzphoneGroup singleflight.Group
// 使用单飞机制防止缓存击穿
func getWzPhone() (string, error) {
    v, err, _ := wzphoneGroup.Do("wzphone", func() (interface{}, error) {
        if phone, found := configs.CRdb.Get("wzphone"); found {
            return phone.(string), nil
        }
        var user configs.User
        if err := configs.DB.Where("role = ?", "admin").First(&user).Error; err != nil {
            if errors.Is(err, gorm.ErrRecordNotFound) {
                return "", fmt.Errorf("管理员用户为空")
            }
            return "", fmt.Errorf("数据库查询失败: %v", err)
        }
        configs.CRdb.Set("wzphone", user.Phone, 1*time.Hour)
        return user.Phone, nil
    })
    if err != nil {
        return "", err
    }
    return v.(string), nil
}

// 动态密钥协商接口
func CreateSession(c *gin.Context) {
	// 生成 16 字节的随机数据（32 个十六进制字符）
	key := make([]byte, 16)
	_, err := rand.Read(key)
	if err != nil {
		JsonResponse(c, http.StatusInternalServerError, "Error generating random key", nil)
		return
	}
	aesKey := hex.EncodeToString(key)
    // 生成会话 ID 并将aesKey保存到缓存
    sessionID := uuid.New().String()
    configs.CRdb.Set("session:"+sessionID, aesKey, 5*time.Minute)  //5分钟
    fmt.Println("密钥", aesKey)
    // 返回AES 密钥和会话 ID
    JsonResponse(c, http.StatusOK, "success", gin.H{
        "session_id":   sessionID,
        "session_key":  aesKey,
    })
}

// 分页获取查询列表
func Index(c *gin.Context) {
	var query configs.FormQuery
	if !bindJSON(c, &query, "参数错误") { return }
    // loc, _ := time.LoadLocation("Asia/Shanghai")  // 例如：上海时区
    // currentTime := time.Now().In(loc)
    // fmt.Println(currentTime)  //2025-02-08 16:53:59.846121549 +0800 CST
    cx := configs.DB.Model(&configs.FormSchema{}).Order("id DESC").
        Where(
            configs.DB.Where("JSON_LENGTH(cxtj) > 0 AND JSON_LENGTH(kfcx) > 0").Or("JSON_LENGTH(kftb) > 0 AND JSON_LENGTH(kftb) > 0"),
        )
        // Where("(start_time IS NULL OR start_time <= ?)", currentTime).
        // Where("(end_time IS NULL OR end_time > ?)", currentTime)
    	
	if query.Search != "" {
		cx.Where("formname LIKE ?", "%"+query.Search+"%")
	}
	// 根据条件显示 1.全开放, 2.登录可见, 3.管理员，4.指定填报员
    user := GetCurrentUser(c)
    if user != nil {
        switch user.Role {
        case "admin":
            // 管理员无过滤条件，查看所有数据
        case "xmgly":
            // 项目管理员能看到 1、2、4 类项目，或自己创建的项目
            cx.Where("(qtxs IN (?, ?, ?) OR created_by = ?)", "全开放", "登录可见", "指定填报员", user.ID)
        case "tby":
            // 填报员能看到 1、2 类项目，或 4 类项目中自己在 tby 列表中的项目
            cx.Where("(qtxs IN (?, ?) OR (qtxs = ? AND JSON_CONTAINS(tby, JSON_ARRAY(?)))", "全开放", "登录可见", "指定填报员", user.ID)
        default:
            // 普通用户只能看到 1、2 类项目
            cx.Where("qtxs IN (?, ?)", "全开放", "登录可见")
        }
    } else {
        cx.Where("qtxs = ?", "全开放") // 未登录用户仅看全开放
    }
	var total int64
	var forms []configs.FormSchema
	if err := cx.Count(&total).Scopes(configs.Paginate(query.Page, query.PageSize)).Find(&forms).Error; err != nil {
		JsonResponse(c, http.StatusInternalServerError, "数据查询失败", nil)
		return
	}
    name := configs.Config.GetString("server.name")
    phone, err := getWzPhone()  // 安全获取手机号
    if err != nil {
        JsonResponse(c, http.StatusInternalServerError, err.Error(), nil)
        return
    }
	JsonResponse(c, http.StatusOK, "获取成功", configs.FormListResponse{
        Config: configs.Wzconfig{
            Name:  name,
            Phone: phone,
        },
		Items: forms,
		Total: total,
	})
}

//锁定查询
func Locke(c *gin.Context) {
    lockUnlock(c, true)
}

//解锁查询
func UnLocke(c *gin.Context) {
    lockUnlock(c, false)
}

type CxQuery struct {
    ID       int                    `form:"id" json:"id" binding:"required"`
    Page     int                    `form:"page" json:"page" binding:"min=1"`
    PageSize int                    `form:"pageSize" json:"pageSize" binding:"min=1,max=1000"`
    Input    map[string]interface{} `form:"input" json:"input"` // 动态接收键值对
}

type Cxjgs struct {
    Bgsx  configs.FormSchema        `json:"bgsx"`
    Items []map[string]interface{}  `json:"items"`
    Total int64                     `json:"total"`
}

type DbCxjgs struct {
    Formname    string                         `json:"formname"`
    Fields      map[string]configs.FieldConfig `json:"fields"`
    Kfcx        []string                       `json:"kfcx"`
    Items       []map[string]interface{}       `json:"items"`
}

// 获取项目属性
func Getbgsx(c *gin.Context) {
    var data struct {
        ID uint `json:"id" binding:"required"`
    }
    if !bindJSON(c, &data, "无效的ID") { return }
    var bgsx configs.FormSchema
    if !fetchFormSchemaByID(c, data.ID, &bgsx) { return }
    // currentUser := GetCurrentUser(c)
    // if bgsx.Wytb || configs.InArray(bgsx.Qtxs, []string{"登录可见", "管理员", "指定填报员"}){
    //     if currentUser == nil {
    //         JsonResponse(c, http.StatusUnauthorized, "请先登录", nil)
    //         return
    //     }
    // }
    JsonResponse(c, http.StatusOK, "获取成功", bgsx)
}

// 从项目bm和行id中获取数据，加入查询条件防泄密
func Getformid(c *gin.Context) {
    var query struct {
        Bm      string            `json:"bm" binding:"required"`
        ID      uint              `json:"id" binding:"required"`
        Input   map[string]string `json:"input"` // 查询条件 {k0:张三}
    }
    if !bindJSON(c, &query, "无效参数") {
        return
    }
    if query.Input == nil || len(query.Input) == 0 {
        JsonResponse(c, http.StatusBadRequest, "输入条件为空", nil)
        return
    }
    var data []map[string]interface{}
    dbQuery := configs.DB.Table(query.Bm).Where("id = ?", query.ID)
    for key, value := range query.Input {
        if(key == "" || value == "") {
            JsonResponse(c, http.StatusNotFound, "查询条件或输入为空", nil)
            return
        }
        dbQuery = dbQuery.Where(key+" = ?", value)
    }
    if err := dbQuery.Find(&data).Error; err != nil {
        JsonResponse(c, http.StatusInternalServerError, "数据获取失败", nil)
        log.Printf("Error retrieving data from table %s for ID %d: %v", query.Bm, query.ID, err) // 打印错误日志
        return
    }
    if len(data) == 0 {
        JsonResponse(c, http.StatusNotFound, "数据不存在", nil)
        return
    }
    JsonResponse(c, http.StatusOK, "获取成功", data)
}

// 统一错误处理
func handleError(c *gin.Context, err error) {
    log.Printf("请求处理失败: %v", err)
    statusCode := http.StatusInternalServerError
    message := "服务器内部错误"
    switch {
    case strings.Contains(err.Error(), "配置不存在"):
        statusCode = http.StatusNotFound
        message = err.Error()
    case strings.Contains(err.Error(), "未启用"):
        statusCode = http.StatusForbidden
        message = err.Error()
    case containsAny(err.Error(), "参数", "配置", "不能为空", "必须填写", "重复提交", "输入为空"):
        statusCode = http.StatusBadRequest
        message = err.Error()
    case strings.Contains(err.Error(), "数据不存在"):
        statusCode = http.StatusNotFound
        message = err.Error()
    case strings.Contains(err.Error(), "每个用户仅允许提交一条数据"):
        statusCode = http.StatusConflict // 409 Conflict表示资源冲突
        message = err.Error()
    }
    JsonResponse(c, statusCode, message, nil)
}

//前端修改和填报行
func QdAddOreditRow(c *gin.Context) {
	var rowdata RowData
	if err := c.ShouldBindJSON(&rowdata); err != nil {
		JsonResponse(c, http.StatusBadRequest, StatusInvalidParams, nil)
		return
	}
    // 更新时判断 Input 是否为空
    if rowdata.Tid > 0 && (rowdata.Input == nil || len(rowdata.Input) == 0) {
        JsonResponse(c, http.StatusInternalServerError, "输入为空", nil)
        return
    }
    // 移除预约字段，防止插入空值报错
    reservationFields := []string{"reservation_date", "slot_start", "slot_end", "sequence_number", "verification_code", "used", "used_time", "operator_id"}
    for _, field := range reservationFields {
        delete(rowdata.Row, field)
    }
	var bgsx configs.FormSchema
	if err := configs.DB.Where("id = ?", uint(rowdata.ID)).First(&bgsx).Error; err != nil {
		JsonResponse(c, http.StatusInternalServerError, "该查询不存在", err)
        return
	}
    if bgsx.TableName == "" { 
        JsonResponse(c, http.StatusInternalServerError, "表名为空", nil)
        return
    }
    // 唯一填报、前台显示状态为2.登录可见, 3.管理员，4.指定填报员 时都需要登录
    currentUser := GetCurrentUser(c)
    if bgsx.Wytb || configs.InArray(bgsx.Qtxs, []string{"登录可见", "管理员", "指定填报员"}){
        if currentUser == nil {
            JsonResponse(c, http.StatusUnauthorized, "请先登录", nil)
            return
        }
        // 强制覆盖创建者字段（防止前端篡改）
        rowdata.Row["cjz"] = currentUser.ID
    }
    err := configs.DB.Transaction(func(tx *gorm.DB) error {
		if rowdata.Tid > 0 {
		    //是否存在id = rowdata.Tid的数据，如果存在则更新，不存在则是篡改数据提示禁止修改
            cxtj, kfcx, zdsz, err := validateParameters(bgsx)
            if err != nil { return err }
            if err := validateInput(rowdata.Input, cxtj, zdsz, bgsx.Sfbt); err != nil {
                return err
            }
            // 校验表单数据
            if err := ValidateFields(rowdata.Row, zdsz, configs.MyURL); err != nil {
        		return err
        	}
		    query := CxQuery{
                ID:       int(bgsx.ID),
                Page:     1,
                PageSize: 1,
                Input:   rowdata.Input,
            }
            _, total, err := buildAndExecuteQuery(tx, bgsx, query, kfcx, zdsz, rowdata.Tid)
            if err != nil { return err }
            if total == 0 { return fmt.Errorf("数据不存在") }
			if err := tx.Table(bgsx.TableName).Where("id = ?", rowdata.Tid).Updates(rowdata.Row).Error; err != nil {
				return fmt.Errorf("更新失败: %w", err)
			}
		} else {
            // 唯一填报校验（仅在开启时执行）
            if bgsx.Wytb {
                var existingCount int64
                if err := tx.Table(bgsx.TableName).Where("cjz = ?", currentUser.ID).Count(&existingCount).Error; err != nil {
                    return fmt.Errorf("唯一性验证失败: %w", err)
                }
                if existingCount > 0 {
                    return fmt.Errorf("每个用户仅允许提交一条数据")
                }
            } else {
                // 非唯一填报时的创建者处理
                if cjzValue, exists := rowdata.Row["cjz"]; !exists || !IsValidCjz(cjzValue) {
                    if rowdata.Userid != 0 {
                        rowdata.Row["cjz"] = rowdata.Userid
                    } else if currentUser != nil {
                        // 允许非登录用户提交时不设置cjz
                        rowdata.Row["cjz"] = currentUser.ID
                    }
                }
            }
            if err := tx.Table(bgsx.TableName).Create(rowdata.Row).Error; err != nil {
                // 捕获唯一约束错误（二次保障）
                if strings.Contains(err.Error(), "Duplicate entry") {
                    return fmt.Errorf("禁止重复提交数据")
                }
                return fmt.Errorf("创建失败: %w", err)
            }
		}
        return nil
    })
    if err != nil {
        handleError(c, err)
        return
    }
	JsonResponse(c, http.StatusOK, "保存成功", rowdata.Row)
}

// 锁定或解锁查询
func lockUnlock(c *gin.Context, lock bool) {
    var lockedata struct {
        TableName string                 `json:"tablename" binding:"required"`
        ID        uint                   `json:"id" binding:"required"`
        Input     map[string]interface{} `json:"input"`
    }
    if !bindJSON(c, &lockedata, "参数错误") { return }
    if !validateNotEmpty(c, lockedata.TableName, "表名为空") { return }
    var bgsx configs.FormSchema
    if !fetchFormSchemaByTableName(c, lockedata.TableName, &bgsx) { return }
    if lock {
        cxtj, _, zdsz, err := validateParameters(bgsx)
        if err != nil {
            handleError(c, err)
            return
        }
        if err := validateInput(lockedata.Input, cxtj, zdsz, bgsx.Sfbt); err != nil {
            handleError(c, err)
            return
        }
    }
    lockStatus := 0
    if lock { lockStatus = 1 }
    err := configs.DB.Transaction(func(tx *gorm.DB) error {
        var count int64
        if err := tx.Table(lockedata.TableName).Where(lockedata.Input).
            Where("id = ?", lockedata.ID).Count(&count).Error; err != nil {
            return err
        }
        if count == 0 { return fmt.Errorf("记录不存在或条件不满足") }
        return tx.Table(lockedata.TableName).Where("id = ?", lockedata.ID).Update("is_locked", lockStatus).Error
    })
    if err != nil {
        handleError(c, err)
        return
    }
    action := "锁定"
    if !lock { action = "解锁" }
    JsonResponse(c, http.StatusOK, action+"成功", nil)
}

// 多表联查
func MultiTable(c *gin.Context) {
    var query CxQuery
    if !bindJSON(c, &query, "参数错误") { return }
    // 判断 query.Input 是否为空
    if query.Input == nil || len(query.Input) == 0 {
        JsonResponse(c, http.StatusInternalServerError, "输入为空", nil)
        return
    }
    var res struct {
        Data     []DbCxjgs          `json:"data"`
        MainConf configs.FormSchema `json:"mainbgsx"`
    }
    err := configs.DB.Transaction(func(tx *gorm.DB) error {
        if err := getFormSchema(tx, uint(query.ID), &res.MainConf); err != nil {
            return fmt.Errorf("主配置获取失败: %w", err)
        }
        if !res.MainConf.Dblc { return fmt.Errorf("多表联查未开启") }
        opts, err := parseLinkOptions(res.MainConf.Dblcxx)
        if err != nil { return err }
        res.Data = processOptions(tx, opts, query)
        return nil
    })
    if err != nil {
        handleError(c, err)
        return
    }
    JsonResponse(c, http.StatusOK, "成功", res)
}

// 普通查询结果
func Cxjg(c *gin.Context) {
    var query CxQuery
    if !bindJSON(c, &query, "参数格式错误") { return }
    var (
        response       *Cxjgs
        asyncTableName string
        asyncData      []map[string]interface{}
    )
    // 判断 query.Input 是否为空
    if query.Input == nil || len(query.Input) == 0 {
        JsonResponse(c, http.StatusInternalServerError, "输入为空", nil)
        return
    }
    err := configs.DB.Transaction(func(tx *gorm.DB) error {
        var bgsx configs.FormSchema
        if err := getFormSchema(tx, uint(query.ID), &bgsx); err != nil {
            return fmt.Errorf("该查询不存在: %w", err)
        }
        if bgsx.TableName == "" { return fmt.Errorf("表名为空") }
        cxtj, kfcx, zdsz, err := validateParameters(bgsx)
        if err != nil { return err }
        if err := validateInput(query.Input, cxtj, zdsz, bgsx.Sfbt); err != nil {
            return err
        }
        data, total, err := buildAndExecuteQuery(tx, bgsx, query, kfcx, zdsz, 0)
        if err != nil { return err }
        asyncTableName = bgsx.TableName
        asyncData = data
        response = &Cxjgs{Bgsx: bgsx, Items: data, Total: total}
        return nil
    })
    if err != nil {
        handleError(c, err)
        return
    }
    go asyncUpdateQueryCount(asyncTableName, asyncData)
    JsonResponse(c, http.StatusOK, "获取成功", response)
}

// 辅助函数：绑定JSON请求并处理错误
func bindJSON(c *gin.Context, data interface{}, errorMsg string) bool {
    if err := c.ShouldBindJSON(data); err != nil {
        JsonResponse(c, http.StatusBadRequest, errorMsg, nil)
        return false
    }
    return true
}

// 辅助函数： 解析多表属性
func parseLinkOptions(config datatypes.JSON) ([]configs.Dblcxx, error) {
    var opts []configs.Dblcxx
    if err := json.Unmarshal([]byte(config), &opts); err != nil {
        return nil, fmt.Errorf("配置解析失败: %w", err)
    }
    return opts, nil
}

// 辅助函数： 事务获取项目属性
func getFormSchema(tx *gorm.DB, id uint, result interface{}) error {
    if err := tx.First(result, "id = ?", id).Error; err != nil {
        if errors.Is(err, gorm.ErrRecordNotFound) {
            return fmt.Errorf("配置不存在")
        }
        return fmt.Errorf("数据库查询错误: %w", err)
    }
    return nil
}

// 辅助函数：根据ID获取表单配置
func fetchFormSchemaByID(c *gin.Context, id uint, result *configs.FormSchema) bool {
    if err := configs.DB.Where("id = ?", id).First(result).Error; err != nil {
        status := http.StatusInternalServerError
        msg := "查询失败"
        if errors.Is(err, gorm.ErrRecordNotFound) {
            status = http.StatusNotFound
            msg = "未找到数据"
        }
        JsonResponse(c, status, msg, nil)
        return false
    }
    return true
}

// 辅助函数：根据表名获取表单配置
func fetchFormSchemaByTableName(c *gin.Context, tableName string, result *configs.FormSchema) bool {
    if err := configs.DB.Where("tablename = ?", tableName).First(result).Error; err != nil {
        status := http.StatusInternalServerError
        msg := "查询配置失败"
        if errors.Is(err, gorm.ErrRecordNotFound) {
            status = http.StatusNotFound
            msg = "该查询不存在"
        }
        JsonResponse(c, status, msg, nil)
        return false
    }
    return true
}

// 辅助函数： 获取联表项目数据
func processOptions(tx *gorm.DB, opts []configs.Dblcxx, query CxQuery) (result []DbCxjgs) {
    for _, opt := range opts {
        if data, err := processSingleOption(tx, opt, query); err == nil {
            result = append(result, data)
        }
    }
    return
}

// 辅助函数： 获取单项目数据
func processSingleOption(tx *gorm.DB, opt configs.Dblcxx, query CxQuery) (DbCxjgs, error) {
    var conf configs.FormSchema
    if err := getFormSchema(tx, uint(opt.ID), &conf); err != nil {
        return DbCxjgs{}, fmt.Errorf("%s: %w", opt.Title, err)
    }
    if conf.TableName == "" {
        return DbCxjgs{}, fmt.Errorf("%s表名缺失", opt.Title)
    }
    cxtj, kfcx, zdsz, err := validateParameters(conf)
    if err != nil || len(cxtj) == 0 {
        return DbCxjgs{}, fmt.Errorf("参数验证失败: %w", err)
    }
    inputVal, err := extractSingleInput(query.Input)
    if err != nil {
        return DbCxjgs{}, err
    }
    data, total, err := buildAndExecuteQuery(tx, conf, createSubQuery(query, cxtj[0], inputVal), kfcx, zdsz, 0)
    if err != nil {
        return DbCxjgs{}, err
    }
    if total == 0 {
        return DbCxjgs{}, fmt.Errorf("未查询到")
    }
    return DbCxjgs{Formname: conf.FormName, Fields: zdsz, Kfcx: kfcx, Items: data}, nil
}

// 辅助函数： 构建查询参数
func createSubQuery(q CxQuery, field, value string) CxQuery {
    return CxQuery{
        ID:       q.ID,
        Page:     q.Page,
        PageSize: q.PageSize,
        Input:    map[string]interface{}{field: value},
    }
}

// 辅助函数： 获取输入值
func extractSingleInput(inputs map[string]interface{}) (string, error) {
    for _, v := range inputs {
        if s, ok := v.(string); ok && s != "" {
            return s, nil
        }
    }
    return "", fmt.Errorf("无效输入")
}

// 辅助函数：校验必填字段
func validateNotEmpty(c *gin.Context, value, errorMsg string) bool {
    if value == "" {
        JsonResponse(c, http.StatusBadRequest, errorMsg, nil)
        return false
    }
    return true
}

// 参数校验封装
func validateParameters(bgsx configs.FormSchema) ([]string, []string, map[string]configs.FieldConfig, error) {
    var cxtj []string
    if err := json.Unmarshal([]byte(bgsx.Cxtj), &cxtj); err != nil {
        return nil, nil, nil, fmt.Errorf("查询条件配置解析失败: %v", err)
    }
    if len(cxtj) == 0 {
        return nil, nil, nil, fmt.Errorf("查询条件不能为空")
    }
    var kfcx []string
    if err := json.Unmarshal([]byte(bgsx.Kfcx), &kfcx); err != nil {
        return nil, nil, nil, fmt.Errorf("开放列配置解析失败: %v", err)
    }
    if len(kfcx) == 0 {
        return nil, nil, nil, fmt.Errorf("开放列不能为空")
    }
    kfcx = append(kfcx, "ID")
    zdsz, err := configs.ParseFieldConfig(bgsx.Fields)
    if err != nil {
        return nil, nil, nil, fmt.Errorf("字段配置解析失败: %v", err)
    }
    return cxtj, kfcx, zdsz, nil
}

// 输入验证封装
func validateInput(input map[string]interface{}, cxtj []string, zdsz map[string]configs.FieldConfig, sfbt bool) error {
    // 检查非法字段
    for zdm := range input {
        if !configs.InArray(zdm, cxtj) {
            return fmt.Errorf("%s 不是查询条件", zdsz[zdm].Name)
        }
    }
    // 检查必填字段
    if sfbt {
        for _, zdm := range cxtj {
            if _, ok := input[zdm]; !ok {
                return fmt.Errorf("%s 必须填写", zdsz[zdm].Name)
            }
        }
    }
    // 字段值校验
    for zdm, _ := range input {
        _, ok := zdsz[zdm]
        if !ok {
            return fmt.Errorf("字段: %s 不是查询条件", zdsz[zdm].Name)
        }
    }
    return nil
}

// 查询构建与执行
func buildAndExecuteQuery(tx *gorm.DB, bgsx configs.FormSchema, query CxQuery, kfcx []string, zdsz map[string]configs.FieldConfig, tid uint) ([]map[string]interface{}, int64, error) {
    builder := tx.Table(bgsx.TableName).Select(kfcx).Where("is_locked = 0").Order("id DESC")
    if tid > 0 {
        builder = builder.Where("id = ?", tid)
    }
    // 统一条件处理逻辑
    conditions := make(map[string]interface{})
    var queryErrors []string
    for zdm, val := range query.Input {
        // 必填字段校验
        if bgsx.Sfbt {
            if isEmptyValue(val) {
                queryErrors = append(queryErrors, fmt.Sprintf("%s 不能为空", zdsz[zdm].Name))
            } else {
                conditions[zdm] = val
            }
        } else {
            // 非必填字段过滤空值
            if !isEmptyValue(val) {
                conditions[zdm] = val
            }
        }
    }
    // 统一错误处理
    if len(queryErrors) > 0 {
        return nil, 0, fmt.Errorf(strings.Join(queryErrors, "，"))
    }
    if len(conditions) == 0 && !bgsx.Sfbt {
        return nil, 0, fmt.Errorf("至少需要输入一个有效条件")
    }
    // 统一条件应用
    if bgsx.Mhcx {
        // 模糊查询处理（支持多类型）
        var hasValidCondition bool
        for zdm, val := range conditions {
            switch v := val.(type) {
            case string:
                builder = builder.Where(zdm+" LIKE ?", "%"+v+"%")
                hasValidCondition = true
            case int, float64:
                builder = builder.Where(zdm+" LIKE ?", fmt.Sprintf("%%%v%%", v))
                hasValidCondition = true
            default:
                // 处理非常规类型
                strVal := fmt.Sprintf("%v", v)
                if strVal != "" {
                    builder = builder.Where(zdm+" LIKE ?", "%"+strVal+"%")
                    hasValidCondition = true
                }
            }
        }
        if !hasValidCondition && !bgsx.Sfbt {
            return nil, 0, fmt.Errorf("至少需要输入一个有效条件")
        }
    } else {
        // 精确查询
        builder = builder.Where(conditions)
    }
    // 获取总数
    var total int64
    if err := builder.Count(&total).Error; err != nil {
        return nil, 0, fmt.Errorf("查询总数失败: %v", err)
    }
    // 分页查询
    if query.Page > 0 && query.PageSize > 0 {
        builder = builder.Scopes(configs.Paginate(query.Page, query.PageSize))
    }
    var data []map[string]interface{}
    if err := builder.Find(&data).Error; err != nil {
        return nil, 0, fmt.Errorf("查询数据失败: %v", err)
    }
    return data, total, nil
}

// 判断是否零值
func isEmptyValue(v interface{}) bool {
    return v == nil || v == "" || v == 0
}

// 异步批量更新
func asyncUpdateQueryCount(tableName string, data []map[string]interface{}) {
    if len(data) == 0 {
        log.Printf("数据为空")
        return
    }
    ids := make([]uint64, 0, len(data))
    for _, record := range data {
        ids = append(ids, record["ID"].(uint64))
    }
    if len(ids) > 0 {
        go batchUpdate(tableName, ids)
    }
}

// 批量更新查询次数
func batchUpdate(tableName string, ids []uint64) {
    batchSize := 500
    for i := 0; i < len(ids); i += batchSize {
        end := i + batchSize
        if end > len(ids) {
            end = len(ids)
        }
        batch := ids[i:end]
        // 使用UpdateColumn替代Update，避免自动更新时间戳
        if err := configs.DB.Table(tableName).Where("id IN (?)", batch).
            UpdateColumn("query_count", gorm.Expr("query_count + 1")).Error; err != nil {
            log.Printf("批量更新query_count失败: %v", err)
        }
    }
}

// 辅助函数检查多个关键字 
func containsAny(s string, substrs ...string) bool {
    for _, substr := range substrs {
        if strings.Contains(s, substr) {
            return true
        }
    }
    return false
}